/*
 * Copyright 2008 Nathan C Jones
 * 
 * This file is part of Fivehundred.
 * 
 * Fivehundred is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * Fivehundred is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Fivehundred. If not, see <http://www.gnu.org/licenses/>. 
 */

package com.googlecode.fivehundred.model;

/**
 * A card is the basic unit of any game. A card consists of a suit and a face
 * value.
 * 
 * @author Nathan C Jones
 */
public interface Card extends Comparable<Card> {

	Card FIVE_OF_SPADES = new DefaultCard(Suit.Spades, Face.Five, 2);

	Card SIX_OF_SPADES = new DefaultCard(Suit.Spades, Face.Six, 7);

	Card SEVEN_OF_SPADES = new DefaultCard(Suit.Spades, Face.Seven, 10);

	Card EIGHT_OF_SPADES = new DefaultCard(Suit.Spades, Face.Eight, 14);

	Card NINE_OF_SPADES = new DefaultCard(Suit.Spades, Face.Nine, 18);

	Card TEN_OF_SPADES = new DefaultCard(Suit.Spades, Face.Ten, 22);

	Card JACK_OF_SPADES = new DefaultCard(Suit.Spades, Face.Jack, 27);

	Card QUEEN_OF_SPADES = new DefaultCard(Suit.Spades, Face.Queen, 30);

	Card KING_OF_SPADES = new DefaultCard(Suit.Spades, Face.King, 34);

	Card ACE_OF_SPADES = new DefaultCard(Suit.Spades, Face.Ace, 38);

	Card FIVE_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Five, 3);

	Card SIX_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Six, 6);

	Card SEVEN_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Seven, 11);

	Card EIGHT_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Eight, 15);

	Card NINE_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Nine, 19);

	Card TEN_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Ten, 23);

	Card JACK_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Jack, 26);

	Card QUEEN_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Queen, 31);

	Card KING_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.King, 35);

	Card ACE_OF_CLUBS = new DefaultCard(Suit.Clubs, Face.Ace, 39);

	Card FOUR_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Four, 0);

	Card FIVE_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Five, 4);

	Card SIX_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Six, 8);

	Card SEVEN_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Seven, 12);

	Card EIGHT_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Eight, 16);

	Card NINE_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Nine, 20);

	Card TEN_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Ten, 24);

	Card JACK_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Jack, 28);

	Card KING_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.King, 36);

	Card ACE_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Ace, 40);

	Card FOUR_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Four, 1);

	Card FIVE_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Five, 5);

	Card SIX_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Six, 9);

	Card SEVEN_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Seven, 13);

	Card EIGHT_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Eight, 17);

	Card NINE_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Nine, 21);

	Card TEN_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Ten, 25);

	Card JACK_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Jack, 29);

	Card QUEEN_OF_DIAMONDS = new DefaultCard(Suit.Diamonds, Face.Queen, 32);

	Card QUEEN_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Queen, 33);

	Card KING_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.King, 37);

	Card ACE_OF_HEARTS = new DefaultCard(Suit.Hearts, Face.Ace, 41);

	Card JOKER = new DefaultCard(Suit.Wild, Face.Joker, 42) {
		public String getName() {
			return "Joker";
		}
	};

	/**
	 * Get the card's suit.
	 * 
	 * @return the card's suit.
	 */
	Suit getSuit();

	/**
	 * Get the card's face.
	 * 
	 * @return the card's face.
	 */
	Face getFace();

	/**
	 * Get the name of the card.
	 * 
	 * @return the card's name.
	 */
	String getName();

	/**
	 * <p>
	 * Get the value of the card. This value is used to determine the natural
	 * ordering of the cards when sorting.
	 * </p>
	 * <p>
	 * This value does not always indicate which card is <em>stronger</em>
	 * within a game play. For example, the Jack of the trumps suit will be
	 * higher than the Ace of the trumps suit, even though the natural ordering
	 * will tell otherwise.
	 * </p>
	 * <p>
	 * The value is not meaningful when comparing two cards which belong to
	 * different decks.
	 * </p>
	 * 
	 * @return the position of the card within its deck.
	 */
	int getValue();

	/**
	 * Get the card renderer to generate images of this card.
	 * 
	 * @return the card's card renderer.
	 */
	CardRenderer getCardRenderer();
}
